package com.example.baseapp.admin.validator;

import com.example.baseapp.admin.dto.req.MenuReq;
import com.example.baseapp.admin.entity.Role;
import com.example.baseapp.admin.service.MenuService;
import com.example.baseapp.admin.service.RoleService;
import com.example.baseapp.admin.validator.interfaces.MenuParentIdExists;
import com.example.baseapp.admin.validator.interfaces.UniqueMenu;
import com.example.baseapp.base.validator.BaseValidator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.validation.ConstraintValidatorContext;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.stream.Collectors;

/**
 * MenuValidation class
 *
 * @author zhangl
 * @date 2022/4/30 18:43
 */
@Slf4j
public class MenuValidation<T extends Annotation> extends BaseValidator<T, MenuReq> {
    @Resource
    protected MenuService menuService;
    @Resource
    protected RoleService roleService;

    protected  ConstraintValidatorContext context ;
    @Override
    public boolean isValid(MenuReq menu, ConstraintValidatorContext constraintValidatorContext) {
        return menuService == null || predicate.test(menu);
    }
    protected void setMassage(String code, String msg) {
        //禁用默认值
        context.disableDefaultConstraintViolation();
        //重新赋值
        context.buildConstraintViolationWithTemplate(msg)
                .addPropertyNode(code).addConstraintViolation();
    }
    protected void checkRole(List<String> roleStringList){
        //校验权限
        if (!CollectionUtils.isEmpty(roleStringList)) {
            List<Role> roleList = roleService.queryById(roleStringList);
            if (roleStringList.size() != roleList.size()) {
                List<String> list = roleStringList.stream().filter(x -> {
                    return !roleList.stream().anyMatch(role -> x.equals(role.getRoleId()));
                }).collect(Collectors.toList());
                log.warn("roleList not exists :{}", list);
                setMassage("roleId", list.toString() + "权限不存在");
                predicate = c -> false;
            }

        }
    }
    public static class UniqueMenuValidator extends MenuValidation<UniqueMenu> {
        @Override
        public boolean isValid(MenuReq menu, ConstraintValidatorContext constraintValidatorContext) {
           context = constraintValidatorContext;
            //菜单父类为000时不交易
            if (!"0000".equals(menu.getMenuParentId()) && menuService.getMenuByMenuId(menu.getMenuParentId()) == null) {
                setMassage("menuParentId", "上级菜单不存在");
                predicate = c -> false;
            }
            checkRole(menu.getRoles());
            return super.isValid(menu, constraintValidatorContext);
        }

        @Override
        public void initialize(UniqueMenu uniqueMenu) {
            predicate = c -> {
                log.info("开始校验菜单 ... {}", c);
                return menuService.getMenuByMenuId(c.getMenuId()) == null;
            };
        }


    }

    public static class MenuParentIdNotExistsValidator extends MenuValidation<MenuParentIdExists> {
        @Override
        public boolean isValid(MenuReq menu, ConstraintValidatorContext constraintValidatorContext) {
            checkRole(menu.getRoles());
            return super.isValid(menu, constraintValidatorContext);
        }

        @Override
        public void initialize(MenuParentIdExists constraintAnnotation) {
            predicate = c -> {
                log.info("开始校验菜单 ... {}", c);
                return menuService.getMenuByMenuId(c.getMenuParentId()) != null
                        && menuService.getMenuByMenuId(c.getMenuId()) != null;
            };
        }
    }
}
